#include "stdio.h"
#include "windows.h"

#define DEF_PROCESS_NAME		"notepad.exe"

HINSTANCE g_hInstance = NULL;
HHOOK g_hHook = NULL;
HWND g_hWnd = NULL;

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
	switch( dwReason )
	{
        case DLL_PROCESS_ATTACH:
			g_hInstance = hinstDLL;
			break;

        case DLL_PROCESS_DETACH:
			break;	
	}

	return TRUE;
}

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	char szPath[MAX_PATH] = {0,};
	char *p = NULL;

	if( nCode >= 0 )
	{
		// bit 31 : 0 => press, 1 => release 
		if( !(lParam & 0x80000000) )   //判断是否键盘摁下
		{
			GetModuleFileNameA(NULL, szPath, MAX_PATH);     //获取包含一个特定模块的文件的全路径，这个模块必须是由当前运行的进程的生成
															//第一个参数如果为NULL，函数会获取当前进程的运行文件(.exe文件)的全路径。
			p = strrchr(szPath, '\\');

            // 判断是不是由于notepad记事本这个进程
			if( !_stricmp(p + 1, DEF_PROCESS_NAME) )
				{WinExec("calc.exe", 0);
				return 1;
				}
		}
	}

    
	return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

#ifdef __cplusplus
extern "C" {
#endif
	__declspec(dllexport) void HookStart() //将一个应用程序定义的钩子处理过程安装到挂钩链中去
	{
		g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0);
		//H_KEYBOARD，此挂钩只能在Windows NT中被安装,用来对底层的键盘输入事件进行监视
		//KeyboardProc指向对应的钩子处理函数
		//g_hInstance指示了一个动态链接的句柄，若参数dwThreadId指示的线程由当前进程创建,并且相应的挂钩处理过程定义于当前进程相关的代码中,则参数hMod必须被设置为NULL(0).
		//最后一个参数指示了一个线程标识符,挂钩处理过程与线程相关.若此参数值为0,则该挂钩处理过程与所有现存的线程相关.
	}
   
	__declspec(dllexport) void HookStop()
	{
		if( g_hHook )
		{
			UnhookWindowsHookEx(g_hHook);
			g_hHook = NULL;
		}
	}
#ifdef __cplusplus
}
#endif